{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Soring, searching, and counting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.11.2'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "author = 'kyubyong. longinglove@nate.com'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sorting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q1. Sort x along the second axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 4]\n",
      " [1 3]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1,4],[3,1]])\n",
    "out = np.sort(x, axis=1)\n",
    "x.sort(axis=1)\n",
    "assert np.array_equal(out, x)\n",
    "print out"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q2. Sort pairs of surnames and first names and return their indices. (first by surname, then by name)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 0]\n"
     ]
    }
   ],
   "source": [
    "surnames =    ('Hertz',    'Galilei', 'Hertz')\n",
    "first_names = ('Heinrich', 'Galileo', 'Gustav')\n",
    "print np.lexsort((first_names, surnames))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q3. Get the indices that would sort x along the second axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1]\n",
      " [1 0]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1,4],[3,1]])\n",
    "out = np.argsort(x, axis=1)\n",
    "print out"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q4. Create an array such that its fifth element would be the same as the element of sorted x, and it divide other elements by their value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [5 1 6 3 9 8 2 7 4 0]\n",
      "\n",
      "Check the fifth element of this new array is 5, the first four elements are all smaller than 5, and 6th through the end are bigger than 5\n",
      "[2 0 4 3 1 5 8 7 6 9]\n"
     ]
    }
   ],
   "source": [
    "x = np.random.permutation(10)\n",
    "print \"x =\", x\n",
    "print \"\\nCheck the fifth element of this new array is 5, the first four elements are all smaller than 5, and 6th through the end are bigger than 5\\n\", \n",
    "out = np.partition(x, 5)\n",
    "x.partition(5) # in-place equivalent\n",
    "assert np.array_equal(x, out)\n",
    "print out\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q5. Create the indices of an array such that its third element would be the same as the element of sorted x, and it divide other elements by their value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [2 8 3 7 5 6 4 0 9 1]\n",
      "partitioned = [0 1 2 3 4 5 8 6 9 7]\n",
      "indices = [0 1 2 3 4 5 8 6 9 7]\n"
     ]
    }
   ],
   "source": [
    "x = np.random.permutation(10)\n",
    "print \"x =\", x\n",
    "partitioned = np.partition(x, 3)\n",
    "indices = np.argpartition(x, 3)\n",
    "print \"partitioned =\", partitioned\n",
    "print \"indices =\", partitioned\n",
    "assert np.array_equiv(x[indices], partitioned)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Searching"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q6. Get the maximum and minimum values and their indices of x along the second axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [[0 5 9 8 2]\n",
      " [3 7 4 1 6]]\n",
      "maximum values = [9 7]\n",
      "max indices = [2 1]\n",
      "minimum values = [0 1]\n",
      "min indices = [0 3]\n"
     ]
    }
   ],
   "source": [
    "x = np.random.permutation(10).reshape(2, 5)\n",
    "print \"x =\", x\n",
    "print \"maximum values =\", np.max(x, 1)\n",
    "print \"max indices =\", np.argmax(x, 1)\n",
    "print \"minimum values =\", np.min(x, 1)\n",
    "print \"min indices =\", np.argmin(x, 1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q7. Get the maximum and minimum values and their indices of x along the second axis, ignoring NaNs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "maximum values ignoring NaNs = [ 4.  3.]\n",
      "max indices = [1 0]\n",
      "minimum values ignoring NaNs = [ 4.  2.]\n",
      "min indices = [1 1]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[np.nan, 4], [3, 2]])\n",
    "print \"maximum values ignoring NaNs =\", np.nanmax(x, 1)\n",
    "print \"max indices =\", np.nanargmax(x, 1)\n",
    "print \"minimum values ignoring NaNs =\", np.nanmin(x, 1)\n",
    "print \"min indices =\", np.nanargmin(x, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q8. Get the values and indices of the elements that are bigger than 2 in x.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Values bigger than 2 = [3 3 5]\n",
      "Their indices are  (array([0, 1, 1], dtype=int64), array([2, 1, 2], dtype=int64))\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1, 2, 3], [1, 3, 5]])\n",
    "print \"Values bigger than 2 =\", x[x>2]\n",
    "print \"Their indices are \", np.nonzero(x > 2)\n",
    "assert np.array_equiv(x[x>2], x[np.nonzero(x > 2)])\n",
    "assert np.array_equiv(x[x>2], np.extract(x > 2, x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q9. Get the indices of the elements that are bigger than 2 in the flattend x."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 4 5]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1, 2, 3], [1, 3, 5]])\n",
    "print np.flatnonzero(x>2)\n",
    "assert np.array_equiv(np.flatnonzero(x), x.ravel().nonzero())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q10. Check the elements of x and return 0 if it is less than 0, otherwise the element itself."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 0 0]\n",
      " [0 0 0]\n",
      " [1 2 3]]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(-5, 4).reshape(3, 3)\n",
    "print np.where(x <0, 0, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q11. Get the indices where elements of y should be inserted to x to maintain order."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 2, 1, 3], dtype=int64)"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1, 3, 5, 7, 9]\n",
    "y = [0, 4, 2, 6]\n",
    "np.searchsorted(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Counting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Q12. Get the number of nonzero elements in x."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "x = [[0,1,7,0,0],[3,0,0,2,19]]\n",
    "print np.count_nonzero(x)\n",
    "assert np.count_nonzero(x) == len(x[x!=0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
